/*
 ============================================================================
 Page	     : 583-585
 Name        : list.c
 Date	     : 20210409
 Author      : Hbue 18060333
 Copyright   : Your copyright notice
 Description : 支持链表操作的函数
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include "list.h"

/* 局部函数原型 */
static void CopyToNode(Item item, Node * pnode);

/* 接口函数 */
/* 把链表设置为空 */
void InitializeList(List *plist)
{
	*plist = NULL;
}

/* 如果链表为空,返回true */
bool ListIsEmpty(const List *plist)
{
	if(*plist == NULL)
	{
		return true;
	}
	else
	{
		return false;
	}
}

/* 如果链表已满,返回true */
bool ListIsFull(const List *plist)
{
	Node *pt;
	bool full = false;

	pt = (Node *)malloc(sizeof(Node));

	if(pt == NULL)
	{
		full = true;
	}
	else
	{
		full = false;
	}
	free(pt);

	return full;
}

/* 返回节点的数量 */
unsigned int ListItemCount(const List *plist)
{
	unsigned int count = 0;
	Node *pnode = *plist;		/* 设置链表的开始 */

	while(pnode != NULL)
	{
		++count;
		pnode = pnode->next;	/* 设置下一个节点 */
	}

	return count;
}

/* 创建存储项的节点,并将其添加至由plist指向的链表末尾(较慢的实现) */
bool AddItem(Item item, List *plist)
{
	Node * pnew;
	Node * scan = *plist;

	pnew = (Node*)malloc(sizeof(Node));
	if(pnew == NULL)
	{
		return false;		/* 失败时退出函数 */
	}

	CopyToNode(item, pnew);
	pnew->next = NULL;
	if(scan == NULL)		/* 空链表,所以把pnew放在链表的开头 */
	{
		*plist = pnew;		/* pnew放在链表的开头 */
	}
	else
	{
		while(scan->next != NULL)
		{
			scan = scan->next;	/* 找到链表的末尾 */
		}
		scan->next = pnew;		/* 把pnew填加到链表的末尾 */
	}

	return true;
}

/* 访问每个节点并执行pfun指向的函数 */
void Traverse(const List *plist, void(*pfun)(Item item))
{
	Node *pnode = *plist;		/* 设置链表的开始 */

	while(pnode != NULL)
	{
		(*pfun)(pnode->item);	/* 把函数应用于链表中的项 */
		pnode = pnode->next;	/* 前进到下一项 */
	}
}

/* 释放由malloc()分配的内存	*/
/* 设置链表指针为NULL 			*/
void EmptyTheList(List *plist)
{
	Node *psave;

	while(*plist != NULL)
	{
		psave = (*plist)->next;		/* 保存下一个节点的地址 */
		free(*plist);				/* 释放当前节点 */
		*plist = psave;				/* 前进至下一个节点 */
	}
}

/* 局部函数定义 */
/* 把一个项拷贝到节点中 */
static void CopyToNode(Item item, Node *pnode)
{
	pnode->item = item;				/* 拷贝结构 */
}

